package com.cherrish.demo;

import com.cherrish.demo.reflect.Person;

import java.lang.reflect.*;

/**
 * @author cherrish
 * @time 2019-03-19 15:40
 * @name TestReflect
 * @desc:
 */
public class TestReflect {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchFieldException, NoSuchMethodException {
        getFromObject();
    }

    public static void getFromObject() throws ClassNotFoundException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException, NoSuchMethodException {
        Person person = new Person();
        Class<?> personClass1 = person.getClass();
        Class<?> personClass2 = Person.class;
        Class<?> personClass3 = Class.forName("com.cherrish.demo.reflect.Person");

        /*根据class打印类名和包名*/
        System.out.println("打印类名的包名:");
        System.out.println("personClass1 类名："+personClass1.getName()+
                " 包名："+personClass1.getPackage().getName());
        System.out.println("personClass2 类名："+personClass2.getName()+
                " 包名："+personClass2.getPackage().getName());
        System.out.println("personClass3 类名："+personClass3.getName()+
                " 包名："+personClass3.getPackage().getName());


        Constructor<?> constructor[] = personClass1.getConstructors();
        for (int i = 0; i < constructor.length; i++) {
            System.out.println("Person的构造函数："+constructor[i].getName()
                    +" 参数个数："+constructor[i].getParameterCount());
        }

        person = (Person) constructor[0].newInstance();
        person.setName("cherrish");
        person.setAge(11);
        System.out.println("利用无参数的构造函数重新实例化person后的结果："+
                person.toString());

        person = (Person) constructor[1].newInstance("Mr Chen", 22);
        System.out.println("利用带参数的构造函数重新实例化person后的结果："+
                person.toString());

        person = (Person) constructor[0].newInstance();

        Field personNameField = personClass1.getDeclaredField("name");
        personNameField.setAccessible(true);
        personNameField.set(person, "Miss Liu");

        Field personAgeField = personClass1.getDeclaredField("age");
        personAgeField.setAccessible(true);
        personAgeField.set(person, 18);

        System.out.println("利用类类型重新实例化person后的结果："+
                person.toString());


        Field fields[] = personClass1.getDeclaredFields();
        for (int i= 0;  i< fields.length; i++) {
            System.out.println("类中的成员: " + fields[i]);
        }

        Method methods[] = personClass1.getMethods();
        System.out.println("函数名：" + methods[1].getName());
        System.out.println("函数返回类型：" + methods[1].getReturnType());
        System.out.println("函数访问修饰符：" + Modifier.toString(methods[1].getModifiers()));
        System.out.println("函数代码写法： " + methods[1]);

        /*得到接口信息*/
        Class<?> superManClass1 = Class.forName("com.cherrish.demo.reflect.SuperMan");
        Class<?> interfaces[] = superManClass1.getInterfaces();
        for (int i = 0; i < interfaces.length; i++) {
            System.out.println("实现的接口类名: " + interfaces[i].getName() );
        }

        /*调用类中的方法，这个就是动态代理需要用到的，也是反射机制最重要部分*/
        System.out.println("调用无参方法fly()：");
        Method method = superManClass1.getMethod("fly");
        method.invoke(superManClass1.newInstance());
        System.out.println("调用有参方法walk(int a)：");
        method = superManClass1.getMethod("walk",int.class);
        method.invoke(superManClass1.newInstance(),100);

        /*获得类加载器信息*/
        /*superManClass1.getSuperclass()相当于personClass1*/
        String personString = superManClass1.getSuperclass().getClassLoader().getClass().getName();
        String superString = superManClass1.getClassLoader().getClass().getName();
        System.out.println("personString:"+personString);
        System.out.println("superString:"+superString);


    }
}
